package com.lwq.lwqmicoservice.framework.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.lwq.lwqmicoservice.common.exception.FieldException;
import com.lwq.lwqmicoservice.common.model.*;
import com.lwq.lwqmicoservice.common.util.BeanAssistant;
import com.lwq.lwqmicoservice.framework.mapper.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2021/6/11
 */
@Service
public class RoleService {

    @Autowired
    private RoleMapper mapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    public List<SysRole> getRolesByUser(Long userId){
        return mapper.getRoleByUserId(userId, SysRole.ENABLE);
    }

    public List<SysRole> queryList(Dto dto){
        return dto == null? mapper.selectList(new QueryWrapper<SysRole>().eq("status", SysRole.ENABLE)) :
                mapper.selectByMap(dto);
    }

    public List<SysMenu> queryRoleMenu(Long roleId){
        List<RelRoleMenu> relRoleMenuselRoleMenu = roleMenuMapper.selectList(new QueryWrapper<RelRoleMenu>().eq("role_id", roleId));
        if(!relRoleMenuselRoleMenu.isEmpty()){
            return MenuService.recursion(menuMapper.selectList(new QueryWrapper<SysMenu>().in("id",relRoleMenuselRoleMenu.stream().map(e -> e.getMenuId()).collect(Collectors.toList()))));
        }else{
            return null;
        }
    }

    public List<SysPermission> queryRolePermission(Long roleId){
        List<RelRolePermission> relRolePermissions = rolePermissionMapper.selectList(new QueryWrapper<RelRolePermission>().eq("role_id", roleId));
        if(!relRolePermissions.isEmpty()){
            return permissionMapper.selectList(new QueryWrapper<SysPermission>().in("id",relRolePermissions.stream().map(e -> e.getPermissionId()).collect(Collectors.toList())));
        }else{
            return null;
        }
    }


    public List<SysRole> queryRoleUser(Long userId){
        List<RelUserRole> relUserRoles = userRoleMapper.selectList(new QueryWrapper<RelUserRole>().eq("user_id", userId));
        if(!relUserRoles.isEmpty()){
            return mapper.selectList(new QueryWrapper<SysRole>().in("id",relUserRoles.stream().map(e -> e.getRoleId()).collect(Collectors.toList())));
        }else{
            return null;
        }
    }

    public void add(SysRole role){
        if(mapper.selectOne(new QueryWrapper<SysRole>()
                .eq(SysRole.NAME,role.getName()))!= null){
            throw new ApiException("角色名称重复");
        }
        mapper.insert(role);
    }

    public void update(SysRole role){
        if(role.getId() == null){
            throw new FieldException("id不可为空");
        }
        SysRole model = mapper.selectById(role.getId());
        if(!role.getName().equals(model.getName()) &&
                mapper.selectOne(new QueryWrapper<SysRole>().eq(SysRole.NAME, role.getName())) != null){
            throw new ApiException("角色名称重复");
        }
        BeanUtils.copyProperties(role, model, BeanAssistant.getNullPropertyNames(role));
        mapper.updateById(model);
    }

    @Transactional(rollbackFor = Exception.class)
    public void del(Long id){
        rolePermissionMapper.delete(new QueryWrapper<RelRolePermission>().eq("role_id", id));
        roleMenuMapper.delete(new QueryWrapper<RelRoleMenu>().eq("role_id", id));
        mapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void relRolePermissions(Long roleId, List<Long> permissionIds){
        rolePermissionMapper.delete(new QueryWrapper<RelRolePermission>().eq("role_id", roleId));
        for (Long permissionId : permissionIds){
            RelRolePermission relRolePermission = new RelRolePermission();
            relRolePermission.setPermissionId(permissionId);
            relRolePermission.setRoleId(roleId);
            rolePermissionMapper.insert(relRolePermission);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void relRoleMenus(Long roleId, List<Long> menuIds){
        roleMenuMapper.delete(new QueryWrapper<RelRoleMenu>().eq("role_id", roleId));
        for (Long menuId : menuIds){
            RelRoleMenu relRoleMenu = new RelRoleMenu();
            relRoleMenu.setMenuId(menuId);
            relRoleMenu.setRoleId(roleId);
            roleMenuMapper.insert(relRoleMenu);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void relUserRole(Long userId, List<Long> roleIds){
        userRoleMapper.delete(new QueryWrapper<RelUserRole>().eq("user_id", userId));
        for (Long roleId : roleIds){
            RelUserRole relUserRole = new RelUserRole();
            relUserRole.setUserId(userId);
            relUserRole.setRoleId(roleId);
            userRoleMapper.insert(relUserRole);
        }
    }
}
